// HTTP 错误类实现
// @/utils/http/HttpError.ts

import type { ErrorType, RequestConfig } from '@/types/http'

export { ErrorType } from '@/types/http'

export class HttpError extends Error {
  public readonly type: ErrorType
  public readonly code?: number
  public readonly statusCode?: number
  public readonly config?: RequestConfig
  public readonly response?: any
  public readonly timestamp: number
  public readonly requestId?: string

  constructor(
    message: string,
    type: ErrorType,
    code?: number,
    statusCode?: number,
    config?: RequestConfig,
    response?: any
  ) {
    super(message)
    
    // 设置原型链
    Object.setPrototypeOf(this, HttpError.prototype)
    
    this.name = 'HttpError'
    this.type = type
    this.code = code
    this.statusCode = statusCode
    this.config = config
    this.response = response
    this.timestamp = Date.now()
    this.requestId = config?.header?.['X-Request-ID']

    // 捕获堆栈跟踪
    if (Error.captureStackTrace) {
      Error.captureStackTrace(this, HttpError)
    }
  }

  // 是否是取消错误
  get isCancel(): boolean {
    return this.type === 'CANCEL_ERROR'
  }

  // 是否是网络错误
  get isNetwork(): boolean {
    return this.type === 'NETWORK_ERROR'
  }

  // 是否是超时错误
  get isTimeout(): boolean {
    return this.type === 'TIMEOUT_ERROR'
  }

  // 是否是认证错误
  get isAuth(): boolean {
    return this.type === 'AUTH_ERROR'
  }

  // 是否是服务器错误
  get isServer(): boolean {
    return this.type === 'SERVER_ERROR' || (this.statusCode && this.statusCode >= 500)
  }

  // 是否是客户端错误
  get isClient(): boolean {
    return this.type === 'CLIENT_ERROR' || (this.statusCode && this.statusCode >= 400 && this.statusCode < 500)
  }

  // 是否是业务错误
  get isBusiness(): boolean {
    return this.type === 'BUSINESS_ERROR'
  }

  // 获取友好的错误信息
  get friendlyMessage(): string {
    const messages: Record<ErrorType, string> = {
      NETWORK_ERROR: '网络连接失败，请检查您的网络设置',
      TIMEOUT_ERROR: '请求超时，请稍后重试',
      CANCEL_ERROR: '请求已取消',
      SERVER_ERROR: '服务器开小差了，请稍后重试',
      CLIENT_ERROR: '请求参数有误，请检查后重试',
      AUTH_ERROR: '登录已过期，请重新登录',
      BUSINESS_ERROR: this.message || '操作失败，请重试',
      UNKNOWN_ERROR: '未知错误，请稍后重试'
    }
    
    return messages[this.type] || this.message
  }

  // 转换为普通对象
  toObject(): Record<string, any> {
    return {
      name: this.name,
      message: this.message,
      type: this.type,
      code: this.code,
      statusCode: this.statusCode,
      timestamp: this.timestamp,
      requestId: this.requestId,
      stack: this.stack
    }
  }

  // 转换为 JSON
  toJSON(): string {
    return JSON.stringify(this.toObject())
  }

  // 静态方法：判断是否是 HttpError 实例
  static isHttpError(error: any): error is HttpError {
    return error instanceof HttpError
  }

  // 静态方法：从普通错误创建 HttpError
  static from(error: any, type?: ErrorType): HttpError {
    if (HttpError.isHttpError(error)) {
      return error
    }

    const errorType = type || 'UNKNOWN_ERROR'
    const message = error?.message || error?.errMsg || '未知错误'
    
    return new HttpError(message, errorType)
  }
} 